﻿namespace C12_Ex02_Shaked_032675316_Itay_032511057
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using FacebookWrapper;
    using FacebookWrapper.ObjectModel;

    public class FacebookImageMapper
    {
        public event Action FinishedInitializing;

        public const string k_SerializationFileName = "UserImageMapping.bin";

        private Mapper<string, Mapper<string, List<string>>> m_UserMapper;
        private Dictionary<string, List<string>> m_NewPhotos;

        private List<User> m_UsersWithNewPictures;
        private uint m_NewPicturesCount;
        private User m_LoggedinUser;

        public FacebookImageMapper(User i_LoggedInUser)
        {
            m_LoggedinUser = i_LoggedInUser;
            m_NewPicturesCount = 0;
            m_NewPhotos = new Dictionary<string, List<string>>();
            m_UsersWithNewPictures = new List<User>();

            if (i_LoggedInUser != null)
            {
                Initialize();
            }
        }

        protected void Initialize()
        {
            try
            {
                m_UserMapper = Mapper<string, Mapper<string, List<string>>>.DeSerialize(k_SerializationFileName);
            }
            catch
            {
                m_UserMapper = new Mapper<string, Mapper<string, List<string>>>();
            }

            if (!m_UserMapper.InnerDictionary.ContainsKey(m_LoggedinUser.Id))
            {
                m_UserMapper.InnerDictionary[m_LoggedinUser.Id] = new Mapper<string, List<string>>();
            }
            else
            {
                Mapper<string, List<string>> updatedMapper = new Mapper<string, List<string>>();
                foreach (string id in m_UserMapper.InnerDictionary[m_LoggedinUser.Id].InnerDictionary.Keys)
                {
                    foreach (User friend in m_LoggedinUser.Friends)
                    {
                        if (friend.Id == id)
                        {
                            updatedMapper.InnerDictionary[id] = friend.GetPicturesList();
                        }
                    }
                }

                m_NewPhotos = m_UserMapper.InnerDictionary[m_LoggedinUser.Id].InnerDictionary.GetComplement<string, string>(updatedMapper.InnerDictionary);

                foreach (string id in m_NewPhotos.Keys)
                {
                    User friend = m_LoggedinUser.GetFriendById(id);
                    if (friend != null)
                    {
                        m_UsersWithNewPictures.Add(friend);
                    }
                }

                m_NewPicturesCount = (uint)m_NewPhotos.Count;

                m_UserMapper.InnerDictionary[m_LoggedinUser.Id] = updatedMapper;
                Mapper<string, Mapper<string, List<string>>>.Serialize(k_SerializationFileName, m_UserMapper);
            }
        }

        public void AddOrUpdateFriendImages(User i_Friend)
        {
            if (i_Friend != null)
            {
                m_UserMapper.InnerDictionary[m_LoggedinUser.Id].InnerDictionary[i_Friend.Id] = i_Friend.GetPicturesList();
            }

            Mapper<string, Mapper<string, List<string>>>.Serialize(k_SerializationFileName, m_UserMapper);
        }

        public void OnFinishedInitializing()
        {
            if (FinishedInitializing != null)
            {
                FinishedInitializing.Invoke();
            }
        }

        public List<string> GetNewPicturesList(User i_User)
        {
            List<string> pictures = null;
            if (m_NewPhotos.ContainsKey(i_User.Id))
            {
                pictures = m_NewPhotos[i_User.Id];
            }

            return pictures;
        }

        public bool IsFriendMapped(User i_User)
        {
            return m_UserMapper.InnerDictionary[m_LoggedinUser.Id].InnerDictionary.ContainsKey(i_User.Id); 
        }

        public uint NewPicturesCount
        {
            get { return m_NewPicturesCount; }
        }

        public List<User> UsersWithNewPictures
        {
            get { return m_UsersWithNewPictures; }
        }
    }
}
